package com.ysd.lis.service.qc.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.ysd.common.Result;
import com.ysd.lis.entity.lab.LabInstrSetup;
import com.ysd.lis.entity.lab.LabManufacturer;
import com.ysd.lis.entity.lab.LabSupplier;
import com.ysd.lis.entity.qc.QcMaterial;
import com.ysd.lis.entity.qc.QcMaterialItem;
import com.ysd.lis.mapper.lab.LabInstrSetupMapper;
import com.ysd.lis.mapper.qc.QcMaterialMapper;
import com.ysd.lis.request.CommonPageDto;
import com.ysd.lis.request.qc.QcMaterialDto;
import com.ysd.lis.service.SysBasDictDetailService;
import com.ysd.lis.service.qc.QcMaterialItemService;
import com.ysd.lis.service.qc.QcMaterialService;
import com.ysd.util.ToolsUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * cold_chain.t_user 服务实现类
 * </p>
 *
 * @author peng
 * @since 2021-10-08
 */
@Service
@Slf4j
public class QcMaterialServiceImpl extends ServiceImpl<QcMaterialMapper, QcMaterial> implements QcMaterialService {

    @Autowired
    QcMaterialMapper qcMaterialMapper;
    @Autowired
    QcMaterialItemService qcMaterialItemService;
    @Autowired
    LabInstrSetupMapper labInstrSetupMapper;
    @Autowired
    QcMaterialItemServiceImpl qcMaterialItemServiceImpl;
    @Autowired
    SysBasDictDetailService sysBasDictDetailService;

    @Override
    public Result findQcMaterialPageList(CommonPageDto pageParam) {
        Page<QcMaterial> page = new Page<>();
        page.setCurrent(pageParam.getPageIndex());
        page.setSize(pageParam.getPageSize());
        LambdaQueryWrapper<QcMaterial> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(QcMaterial::getDelFlag, 0);
        if (StringUtils.isNotBlank(pageParam.getSeachValue())) {
            lambdaQueryWrapper.and(wrapper -> wrapper.like(QcMaterial::getMaterialName, pageParam.getSeachValue())
                    .or().like(QcMaterial::getQcNo, pageParam.getSeachValue())
                    .or().like(QcMaterial::getBatchNum, pageParam.getSeachValue()));
        }
        if (StringUtils.isNotBlank(pageParam.getPid())) {
            lambdaQueryWrapper.eq(QcMaterial::getInstrId, pageParam.getPid());
        }
        lambdaQueryWrapper.orderByAsc(QcMaterial::getSeq);
        Page<QcMaterial> materialPage = qcMaterialMapper.selectPage(page, lambdaQueryWrapper);
        return Result.succ(1, "查询成功", materialPage);
    }

    @Override
    public Result findMaterialItemTree(CommonPageDto pageParam) {
        //查出所有的质控品
        LambdaQueryWrapper<QcMaterial> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(QcMaterial::getDelFlag, 0);
        if (StringUtils.isNotBlank(pageParam.getIsShowAll())) {
            //0 查询有效期内得  1显示所有得
            if (pageParam.getIsShowAll().equals("0")) {
                queryWrapper.le(QcMaterial::getEnableDate, new Timestamp(new Date().getTime()));
                queryWrapper.ge(QcMaterial::getValidDate, new Timestamp(new Date().getTime()));
                queryWrapper.and(wrapper -> wrapper.isNull(QcMaterial::getStopDate).or().ge(QcMaterial::getStopDate, new Timestamp(new Date().getTime())));

            }
        }
        if(ToolsUtils.isNotEmpty(pageParam.getInstrId())){
            queryWrapper.eq(QcMaterial::getInstrId,pageParam.getInstrId());
        }
        if(ToolsUtils.isNotEmpty(pageParam.getInstrIds())){
            queryWrapper.in(QcMaterial::getInstrId,pageParam.getInstrIds());
        }
        queryWrapper.orderByAsc(QcMaterial::getSeq);
        List<QcMaterial> materialList = qcMaterialMapper.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(materialList)) {
            //查字典
            List<Map<String, Object>> qchorizontals = (List<Map<String, Object>>) sysBasDictDetailService.getSysBasDictList("QCHORIZONTAL").getData();

            List<Map> mList = new ArrayList<>();
            for (QcMaterial qcMaterial : materialList) {
                Map<String, Object> map = new HashMap<>();

                String horizontalDesc;
                String horizontal = qcMaterial.getHorizontal();
                if(StringUtils.isNotBlank(horizontal)){
                    Map<String, Object> code = qchorizontals.stream().filter(a -> a.get("code").equals(horizontal)).findFirst().orElse(null);
                    if(Objects.nonNull(code)){
                        horizontalDesc = code.get("name").toString();
                    }else {
                        horizontalDesc = horizontal;
                    }
                }else {
                    horizontalDesc = horizontal;
                }

                map.put("id", qcMaterial.getId());
                map.put("code", qcMaterial.getQcNo());
                map.put("name", "批号 " + qcMaterial.getBatchNum() + " 水平 " + horizontalDesc + " 启用日期 " + DataFormart(qcMaterial.getEnableDate()) + " 效期 " + DataFormart(qcMaterial.getValidDate()));
                map.put("instrId", qcMaterial.getInstrId());
                map.put("children", new ArrayList<>());
                map.put("isSearch", "0");
                map.put("type", "material");
                mList.add(map);
            }

            //获取仪器ID
            List<String> instrIds = materialList.stream().map(QcMaterial::getInstrId).distinct().collect(Collectors.toList());
            //查仪器
            //List<LabInstrSetup> instrList = labInstrSetupMapper.selectBatchIds(instrIds);

            LambdaQueryWrapper<LabInstrSetup> queryWrapper2 = new LambdaQueryWrapper<>();
            queryWrapper2.eq(LabInstrSetup::getDelFlag, 0)
                    .in(LabInstrSetup::getId,instrIds)
                    .orderByAsc(LabInstrSetup::getCreateTime);
            if(ToolsUtils.isNotEmpty(pageParam.getPoct())){
                queryWrapper2.eq(LabInstrSetup::getPoct, pageParam.getPoct());
            }
            //查仪器
            List<LabInstrSetup> instrList = labInstrSetupMapper.selectList(queryWrapper2);

            List<Map> eqList = new ArrayList<>();
            for (LabInstrSetup instr : instrList) {
                Map<String, Object> map = new HashMap<>();
                map.put("id", instr.getId());
                map.put("code", instr.getInstrCode());
                map.put("name", instr.getInstrName());
                map.put("instrClass", instr.getInstrClass());
                map.put("children", mList.stream().filter(ma -> ma.get("instrId").equals(instr.getId())).collect(Collectors.toList()));
                map.put("isSearch", "1");
                map.put("type", "instr");
                eqList.add(map);
            }
            List<String> classList = instrList.stream().map(LabInstrSetup::getInstrClass).distinct().collect(Collectors.toList());
            //查字典
            List<Map<String, Object>> yqdllist = (List<Map<String, Object>>)sysBasDictDetailService.getSysBasDictList("YQDL").getData();

            List<Map> returnList = new ArrayList<>();

            for (int i = 0; i < classList.size(); i++) {
                String className = classList.get(i);
                Map<String, Object> map = new HashMap();
                map.put("id", i + 1);
                map.put("code", className);
                map.put("name", yqdllist.stream().filter(a -> a.get("code").equals(className)).findFirst().get().get("name"));
                map.put("children", eqList.stream().filter(is -> is.get("instrClass").equals(className)).collect(Collectors.toList()));
                map.put("isSearch", "1");
                map.put("type", "instrClass");
                returnList.add(map);
            }
            return Result.succ(1, "查询成功", returnList);
        }
        return Result.succ(1, "查询成功", null);
    }

    @Override
    public Result findQcMaterialList(CommonPageDto pageParam) {
        MPJLambdaWrapper<QcMaterial> lambdaQueryWrapper = new MPJLambdaWrapper<>();
        lambdaQueryWrapper.selectAll(QcMaterial.class)
                .selectAs("ins", LabInstrSetup::getInstrName, QcMaterial::getInstrName)
                .selectAs("man", LabManufacturer::getManuName,QcMaterial::getManufacturerName)
                .selectAs("man2", LabManufacturer::getManuName,QcMaterial::getCaliManuName)
                .selectAs("sup", LabSupplier::getSupplierName,QcMaterial::getSupplierName)
                .selectAs("sup2", LabSupplier::getSupplierName,QcMaterial::getReagentSupplierName)
                .leftJoin(LabInstrSetup.class, "ins", LabInstrSetup::getId, QcMaterial::getInstrId)
                .leftJoin(LabManufacturer.class,"man",LabManufacturer::getId,QcMaterial::getManufacturer)
                .leftJoin(LabManufacturer.class,"man2",LabManufacturer::getId,QcMaterial::getCaliManu)
                .leftJoin(LabSupplier.class,"sup",LabSupplier::getId,QcMaterial::getSupplier)
                .leftJoin(LabSupplier.class,"sup2",LabSupplier::getId,QcMaterial::getReagentSupplier)
                .eq(QcMaterial::getDelFlag, 0);
        if (StringUtils.isNotBlank(pageParam.getSeachValue())) {
            lambdaQueryWrapper.and(wrapper -> wrapper.like(QcMaterial::getMaterialName, pageParam.getSeachValue())
                    .or().like(QcMaterial::getQcNo, pageParam.getSeachValue())
                    .or().like(QcMaterial::getBatchNum, pageParam.getSeachValue()));
        }
        if (StringUtils.isNotBlank(pageParam.getPid())) {
            lambdaQueryWrapper.eq(QcMaterial::getInstrId, pageParam.getPid());
        }
        if (StringUtils.isNotBlank(pageParam.getIsShowAll())) {
            //0 查询有效期内得  1显示所有得
            if (pageParam.getIsShowAll().equals("0")) {
                lambdaQueryWrapper.le(QcMaterial::getEnableDate, new Timestamp(new Date().getTime()));
                lambdaQueryWrapper.ge(QcMaterial::getValidDate, new Timestamp(new Date().getTime()));
                lambdaQueryWrapper.and(wrapper -> wrapper.isNull(QcMaterial::getStopDate).or().ge(QcMaterial::getStopDate, new Timestamp(new Date().getTime())));

            }
        }
        lambdaQueryWrapper.orderByAsc(QcMaterial::getSeq);
        List<QcMaterial> materialList = qcMaterialMapper.selectList(lambdaQueryWrapper);
        return Result.succ(1, "查询成功", materialList);
    }

    @Override
    public Result findMaterialListByQcDate(CommonPageDto pageParam) {
        String startDate = pageParam.getStartDate();
        String endDate = pageParam.getEndDate();

        MPJLambdaWrapper<QcMaterial> lambdaQueryWrapper = new MPJLambdaWrapper<>();
        lambdaQueryWrapper.selectAll(QcMaterial.class)
                .selectAs("ins", LabInstrSetup::getInstrName, QcMaterial::getInstrName)
                .selectAs("man", LabManufacturer::getManuName,QcMaterial::getManufacturerName)
                .selectAs("man2", LabManufacturer::getManuName,QcMaterial::getCaliManuName)
                .selectAs("sup", LabSupplier::getSupplierName,QcMaterial::getSupplierName)
                .selectAs("sup2", LabSupplier::getSupplierName,QcMaterial::getReagentSupplierName)
                .leftJoin(LabInstrSetup.class, "ins", LabInstrSetup::getId, QcMaterial::getInstrId)
                .leftJoin(LabManufacturer.class,"man",LabManufacturer::getId,QcMaterial::getManufacturer)
                .leftJoin(LabManufacturer.class,"man2",LabManufacturer::getId,QcMaterial::getCaliManu)
                .leftJoin(LabSupplier.class,"sup",LabSupplier::getId,QcMaterial::getSupplier)
                .leftJoin(LabSupplier.class,"sup2",LabSupplier::getId,QcMaterial::getReagentSupplier)
                .eq(QcMaterial::getDelFlag, 0);
        if (StringUtils.isNotBlank(pageParam.getSeachValue())) {
            lambdaQueryWrapper.and(wrapper -> wrapper.like(QcMaterial::getMaterialName, pageParam.getSeachValue())
                    .or().like(QcMaterial::getQcNo, pageParam.getSeachValue())
                    .or().like(QcMaterial::getBatchNum, pageParam.getSeachValue()));
        }
        if (StringUtils.isNotBlank(pageParam.getPid())) {
            lambdaQueryWrapper.eq(QcMaterial::getInstrId, pageParam.getPid());
        }
        Timestamp endTimestamp = null;
        Timestamp startTimestamp = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try{
            Date edate = sdf.parse(endDate + " 23:59:59.99");  // 解析为Date对象
            endTimestamp = new Timestamp(edate.getTime());

            Date sdate = sdf.parse(startDate + " 00:00:00");  // 解析为Date对象
            startTimestamp = new Timestamp(sdate.getTime());
        }catch (Exception e){

        }

        if(ToolsUtils.isNotEmpty(endTimestamp)){
            lambdaQueryWrapper.le(QcMaterial::getEnableDate, endTimestamp);
        }
        if(ToolsUtils.isNotEmpty(startTimestamp)){
            lambdaQueryWrapper.ge(QcMaterial::getValidDate, startTimestamp);
            Timestamp finalStartTimestamp = startTimestamp;
            lambdaQueryWrapper.and(wrapper -> wrapper.isNull(QcMaterial::getStopDate).or().ge(QcMaterial::getStopDate, finalStartTimestamp));
        }

        lambdaQueryWrapper.orderByAsc(QcMaterial::getSeq);
        List<QcMaterial> materialList = qcMaterialMapper.selectList(lambdaQueryWrapper);
        return Result.succ(1, "查询成功", materialList);
    }

    @Override
    public Result addQcMaterial(QcMaterial material) {
        int insert = qcMaterialMapper.insert(material);
        if (insert > 0) {
            return Result.succ(1, "添加成功", material);
        } else {
            return Result.fail(400, "添加失败", "");
        }
    }

    @Override
    public Result editQcMaterial(QcMaterial material) {
        int updateById = qcMaterialMapper.updateById(material);
        if (updateById > 0) {
            return Result.succ(1, "提交成功", material);
        } else {
            return Result.fail(400, "修改失败", "");
        }
    }

    @Override
    public Result batchDeleteQcMaterialList(QcMaterialDto dto) {
        List<QcMaterial> list = dto.getQcMaterialList();
        List<String> ids = list.stream().map(QcMaterial::getId).collect(Collectors.toList());
        //根据质控物IDs查询质控下是否有质控项目
        LambdaQueryWrapper<QcMaterialItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(QcMaterialItem::getDelFlag, 0);
        queryWrapper.in(QcMaterialItem::getMaterialId, ids);
        int cnt = qcMaterialItemService.count(queryWrapper);
        if (cnt > 0) {
            return Result.succ(1, "质控物下有指控项目，不能删除", null);
        }
        boolean b = this.removeByIds(ids);
        if (b) {
            return Result.succ(1, "删除成功", null);
        } else {
            return Result.fail(400, "删除失败", "");
        }
    }

    @Override
    @Transactional
    public Result editQcMaterialAndBatchItem(QcMaterial material) {
        int updateById = qcMaterialMapper.updateById(material);
        if (updateById > 0) {
            List<QcMaterialItem> materialItemList = material.getMaterialItemList();
            if (CollectionUtils.isNotEmpty(materialItemList)) {
                boolean b = qcMaterialItemService.updateBatchById(materialItemList);
                if (b) {
                    return Result.succ(1, "更新成功", null);
                } else {
                    return Result.fail("更新失败！");
                }
            }
            return Result.succ(1, "提交成功", material);
        } else {
            return Result.fail(400, "修改失败", "");
        }
    }

    private String DataFormart(Timestamp timestamp) {
        return DateUtil.format(timestamp, "yyyy/MM/dd");
    }

}
